package val.to;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;

import val.to.HttpUtil.HttpUtilResponse;
import val.to.config.Constants;

import android.util.Log;

public class HttpUtil {
	
	public static class HttpUtilResponse{
		public int code;
		public String content;
		public boolean success;
		
		public HttpUtilResponse(boolean success, int code, String content){
			this.code = code;
			this.content = content;
			this.success = success;
		}
	}
	
	private final static boolean logEnabled = true;
	
	
	
	public static HttpUtilResponse deleteRequest(String path) 
		throws ClientProtocolException, IOException{
	
		DefaultHttpClient httpclient = new DefaultHttpClient();
		HttpDelete httpDelete = new HttpDelete(path);
	
		httpDelete.setHeader("Accept", "application/json");
		httpDelete.setHeader("Content-type", "application/json");
		authRequest(httpDelete);
		
		if (logEnabled){
			Log.d(Constants.TAG, "HTTP DELETE: " + path);
		}
		
		return sendRequest(httpclient, httpDelete);
	}

	public static HttpUtilResponse putRequest(String path, JSONObject json) 
			throws ClientProtocolException, IOException{

			DefaultHttpClient httpclient = new DefaultHttpClient();
			HttpPut httpPut = new HttpPut(path);

			StringEntity se = new StringEntity(json.toString());
			httpPut.setEntity(se);
			httpPut.setHeader("Accept", "application/json");
			httpPut.setHeader("Content-type", "application/json");
			authRequest(httpPut);
			
			if (logEnabled){
				Log.d(Constants.TAG, "HTTP POST: " + json.toString());
			}
			
			return sendRequest(httpclient, httpPut);
		}
	
	public static HttpUtilResponse postRequest(String path) 
			throws ClientProtocolException, IOException{
		return postRequest(path, null);
	}
	
	public static HttpUtilResponse postRequest(String path, JSONObject json) 
		throws ClientProtocolException, IOException{

		DefaultHttpClient httpclient = new DefaultHttpClient();
		HttpPost httpost = new HttpPost(path);

		if (json != null){
			StringEntity se = new StringEntity(json.toString());
			httpost.setEntity(se);
		}
		
		httpost.setHeader("Accept", "application/json");
		httpost.setHeader("Content-type", "application/json");		
		authRequest(httpost);
		
		if (logEnabled){
			Log.d(Constants.TAG, "HTTP POST: " + (json != null ? json.toString() : "No Body"));
		}
		
		return sendRequest(httpclient, httpost);
	}
	
	public static HttpUtilResponse getRequest(String path, Map<String, String> args)
		throws ClientProtocolException, IOException{
            HttpClient client = new DefaultHttpClient(); 
            
            StringBuilder argsStr = new StringBuilder();
            
            
            if (args != null && args.size() > 0){         
	            Iterator<Entry<String, String>> it = args.entrySet().iterator();
	            while (it.hasNext()) {
	            	Entry<String, String> pair = it.next();
	            	argsStr.append(String.format("&%s=%s", pair.getKey(), pair.getValue()));
	            }
	            
	            if(argsStr.length() > 0){
	            	argsStr.replace(0, 1, "?"); //replace the first &
	            }
            }
            
            String uri = String.format("%s%s", path, argsStr);
            HttpGet get = new HttpGet(uri);
            authRequest(get);
            
        	if (logEnabled){
        		Log.d(Constants.TAG, "HTTP GET: " + path);
        	}
        	
        	return sendRequest(client, get);
	}
	
	private static HttpUtilResponse sendRequest(HttpClient client, HttpRequestBase req)
		throws ClientProtocolException, IOException{
		HttpResponse response = client.execute(req);
		int code = response.getStatusLine().getStatusCode();
	    
		if (code != 200 /* HTTP OK */ && code != 204 /* HTTP NO CONTENT */){
	    	Log.e(Constants.TAG, response.getStatusLine().getReasonPhrase());
	    	return new HttpUtilResponse(false, code, null);
	    }
		
	    
        BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuffer sb = new StringBuffer("");
        String line = "";
        String NL = System.getProperty("line.separator");
        while ((line = in.readLine()) != null) {
            sb.append(line + NL);
        }
        in.close();

        return new HttpUtilResponse(true, code, sb.toString());		
	}
	
	private static void authRequest(HttpRequestBase req){
		req.setHeader("facebook-access-token", Globals.FacebookSession.getAccessToken());		
	}
}
